
import re


# s = '"ddddddddddddddll///*oooo"///*eeee"eee'

# pattern = '.*"[^"]*"'

# print re.match(pattern, s)
# print re.sub(pattern, "", s)

# space = "\t"

class SynFlag(object):
	# space = "\t"
	# c_tab = 0
	# macro_tab = 0

	# is_str = False
	# is_muti_com = False
	# is_st_tab = False
	# sentence_end = False
	# sentence_begin = False

	def __init__(self):
		self.space = "\t"
		self.c_tab = 0
		self.macro_tab = 0

		self.is_str = False
		self.is_muti_com = False
		self.is_st_tab = False
		self.sentence_end = False
		self.sentence_begin = False

		self.macro_stack = []

	def __str__(self):
		return  "%d, %d"%(self.c_tab, self.macro_tab)

	def clone(self):
		obj = SynFlag()
		self.copy(self, obj)
		return obj

	def copy(this, self, obj):
		# obj = SynFlag()
		obj.is_str = self.is_str
		obj.is_muti_com = self.is_muti_com
		obj.is_st_tab = self.is_st_tab
		obj.sentence_begin = self.sentence_begin
		obj.sentence_end = self.sentence_end

		obj.c_tab = self.c_tab
		obj.macro_tab = self.macro_tab
		obj.space = self.space

		return obj

	def word_build(self, line):
		# ()[]{}:@*"'\;,\s
		#number 1'b

		ptn = "[0-9a-zA-Z_]"
		words = []
		tword = ""
		is_str = False
		for c in line:
			if c == '"':
				if is_str:
					is_str = False
					tword += c
					words.append(tword)
					tword = ""
				else:
					is_str = True
					if tword != "":
						words.append(tword)
					tword = ""
			if is_str:
				tword += c

			if re.match(ptn, c):
				tword += c
			else:
				if tword != "":
					words.append(tword)
					tword = ""
				words.append(c)
		if tword != "":
			words.append(tword)
		return words


	def quato_macro(self):
		return self.qutao_cnt()
		# return (self.space * self.macro_tab)

	def qutao_cnt(self):
		return (self.space * self.c_tab)

	def format(self, fname, ofname):
		osf = open(ofname, "w")
		with open(fname) as f:
			for line in f.readlines():
				line = line.strip()
				line = self.format_line(line)
				if line != None:
					osf.write(str(line))
		osf.close()


	def format_line(self, line):
		rs = self.statement_any_line(line)
		code_buf = ""
		code_line = ""
		for k in rs:
			line = k[0]
			st_flag = k[1]
			
			if not st_flag:
				if code_buf == "":
					code_buf += self.qutao_cnt() + line
				elif line.startswith("/*"):
					code_buf += line
				elif line.startswith("//"):
					code_buf += "\t\t" + line
				else:
					code_buf += line
			elif line != "":
				code_line += line
				rs = self.intent(line)
				if rs != None:
					code_buf += rs
		return code_buf


	def intent(self, line):
		line = line.strip()
		tline = ""
		if line.startswith("`"):
			l_sp = line.split()

			mac_start = ["`ifdef", "`ifndef"]
			mac_else = ["`else", "`elsif"]
			mac_end = ['`endif']

			start_word = l_sp[0]

			if start_word in mac_start:
				obj = self.clone()
				self.macro_stack.append(obj)
				tline = "\n" + self.quato_macro() + line
				self.macro_tab += 1
			elif start_word.startswith("`endif"):
				obj = self.macro_stack.pop()
				self.copy(obj, self)
				tline = self.quato_macro() + line  + "\n"
			elif start_word in mac_else:
				obj = self.macro_stack[-1]
				self.copy(obj, self)
				tline = self.quato_macro() + line  + "\n"
				self.macro_tab += 1
			else:
				tline = self.quato_macro() + line
		else:

			l_sp = self.word_build(line)

			block_start = ["begin", "case", "casex", "casez", "module", "function"]
			block_end = ["end", "endcase", "endmodule", "endfunction"]

			block_flag_start = ["(", "{", ",", "=", ":", "]", "[", ")", "}"]
			block_flag_end = [";"]

			isflag = False
			isblock = False

			function = ["import", "export"]
			is_dpi_ann = False

			for word in l_sp:
				if word in function:
					is_dpi_ann = True
				elif word in block_start:
					if not is_dpi_ann:
						self.c_tab += 1
						isblock = True
				elif word in block_end:
					self.c_tab -= 1
	
			endword = ""
			isend = False
			if len(l_sp) > 0:
				endword = l_sp[len(l_sp)-1]
				if (endword not in block_end and endword not in block_start 
				and endword not in block_end and not self.sentence_begin):
						isflag = True
						self.c_tab += 1
						self.sentence_end = False
						self.sentence_begin = True

				if not self.sentence_end:
					if endword in block_flag_end:
						self.sentence_end = True
						self.sentence_begin = False
						self.c_tab -= 1
						isend = True

			if isflag:
				self.c_tab -= 1
			if isblock:
				self.c_tab -= 1

			if isend:
				self.c_tab += 1

			tline = self.qutao_cnt() + line

			if isend:
				self.c_tab -= 1

			if isflag:
				self.c_tab += 1
			if isblock:
				self.c_tab += 1
		return tline





	def statement_any_line(self, line):
		# rs_cnt = [(c, T|F)]
		rs_cnt = []
		line = line.strip()
		tstr = ""
		is_cmt = False
		is_pre_cmt = False
		is_muti_cmt = False
		t_is_muti_cmt = False
		is_pre_end_muti_cmt = False
		is_str = False
		lc = ""
		tline = ""
		tcmtline = ""
		tcmt = ""
		is_change = False
		if line.startswith("`"):
			rs_cnt.append((line, True))
		else:
			for c in line:
				if c == '"' and (not is_cmt or not is_muti_cmt):
					if is_str:
						is_str = False
					else:
						is_str = True

				elif c == "/" and not is_str:
					if lc == "/" and not is_muti_cmt and is_pre_cmt:
						is_cmt =True
						is_change = True
						is_pre_cmt =False
					elif lc == "*" and is_muti_cmt and is_pre_end_muti_cmt:
						is_muti_cmt = False
						t_is_muti_cmt = True
						is_pre_cmt = False
					else:
						is_pre_cmt = True
				elif c == "*" and not is_str:
					if lc == "/" and not is_cmt and not is_muti_cmt:
						is_muti_cmt = True
						is_change = True
						is_pre_end_muti_cmt = False
					else:
						is_pre_end_muti_cmt = True

				if is_muti_cmt or is_cmt or t_is_muti_cmt:
					if is_change:
						rs_cnt.append((tline, True))
						is_change = False
						tline = ""
					tcmt += lc
					if lc == "/" and t_is_muti_cmt:
						t_is_muti_cmt = False
						rs_cnt.append((tcmt, False))
						tcmt = ""
				else:
					if is_change:
						rs_cnt.append((tcmt, False))
						is_change = False
					tline += lc
				lc = c

		if is_muti_cmt or is_cmt or t_is_muti_cmt:
			if is_change:
				rs_cnt.append((tline, True))
				is_change = False
			tcmt += lc
			if lc == "/" and t_is_muti_cmt:
				t_is_muti_cmt = False
			rs_cnt.append((tcmt, False))
		else:
			if is_change:
				rs_cnt.append((tcmt, False))
				is_change = False
			tline += lc
			rs_cnt.append((tline, True))
		rs_cnt.append(("\n", False))
		return  rs_cnt

# sf = SynFlag()
# # sf.format("/mnt/hgfs/wrok/dev/workspace/cosim_zebu/xTnC_cpu.v-bak")
# source_fname = "/mnt/hgfs/wrok/dev/workspace/cosim_zebu/zebu/xTnC_cpu.v-bak"
# ofname = "/mnt/hgfs/wrok/dev/workspace/cosim_zebu/xTnC_cpu.sv"

# sf.format(source_fname, ofname)
# # sf.format("/mnt/hgfs/wrok/dev/simple/format/source.v")


# print re.search("[\s]begin[\s]*", "always @(posedge ck_gclkcr) begin")